# -*- coding: UTF-8 -*-
# @Project ：VehicleDimensionMeasurementSystem 
# @File    ：models.py
# @IDE     ：PyCharm 
# @Date    ：2024/6/11 下午10:03

import datetime
from sqlalchemy import String, create_engine, func, ForeignKey, DateTime, Table, Column, Integer, Enum, Boolean, Date, \
    Float
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Mapped, mapped_column, sessionmaker, relationship, declared_attr
from typing_extensions import Annotated, List, Set

engine = create_engine('mysql+pymysql://root:root123@localhost:3306/db_alchemy')
# engine = create_engine('sqlite:////vehicle_sizes.db')
Base = declarative_base()

# 自定义字段
pk = Annotated[int, mapped_column(primary_key=True)]  # ID
title_unique = Annotated[str, mapped_column(String(128), nullable=False, unique=True)]  # 唯一的
create_datetime = Annotated[datetime.datetime, mapped_column(nullable=False, server_default=func.now())]  # 创建时间
update_datetime = Annotated[datetime.datetime, mapped_column(nullable=True, server_onupdate=func.now())]  # 修改时间


class BaseModel(Base):
    """这是一个基础类，包含ID、创建时间、更新时间"""
    __abstract__ = True
    id: Mapped[pk] = mapped_column(info={"description": "主键"})
    create_time: Mapped[create_datetime] = mapped_column(info={"description": "创建时间"})
    update_time: Mapped[update_datetime] = mapped_column(info={"description": "更新时间"})


class PlateAbbreviationModel(BaseModel):
    """号牌简称"""
    __tablename__ = 'plate_abbreviations'
    plate_abbr: Mapped[str] = mapped_column(String(4), nullable=False, unique=True, info={"description": "号牌简称"})
    is_show: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False, info={"description": "是否展示"})


class PlateTypeModel(BaseModel):
    """号牌类型"""
    __tablename__ = 'plate_type'
    code_name: Mapped[str] = mapped_column(String(4), nullable=False, unique=True, info={"description": "代号"})
    plate_type: Mapped[str] = mapped_column(String(32), nullable=False, unique=True, info={"description": "号牌种类"})
    is_show: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False, info={"description": "是否展示"})

    vehicle_info: Mapped[List['VehicleInfoModel']] = relationship(back_populates='plate_type')


class VehicleTypeModel(BaseModel):
    """车辆类型"""
    __tablename__ = 'vehicle_type'
    code_name: Mapped[str] = mapped_column(String(4), nullable=False, unique=True, info={"description": "代号"})
    vehicle_type: Mapped[str] = mapped_column(String(32), nullable=False, unique=True, info={"description": "号牌种类"})
    sort_show: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "展示顺序"})

    vehicle_info: Mapped[List['VehicleInfoModel']] = relationship(back_populates='vehicle_type')


class VehicleClassModel(BaseModel):
    """车辆类别"""
    __tablename__ = 'vehicle_class'
    code_name: Mapped[str] = mapped_column(String(4), nullable=False, unique=True, info={"description": "代号"})
    vehicle_class: Mapped[str] = mapped_column(String(32), nullable=False, unique=True,
                                               info={"description": "车辆种类"})

    vehicle_info: Mapped[List['VehicleInfoModel']] = relationship(back_populates='vehicle_class')


class InspectionCategoryModel(BaseModel):
    """检验类别"""
    __tablename__ = 'inspection_category'
    code_name: Mapped[str] = mapped_column(String(4), nullable=False, unique=True, info={"description": "代号"})
    inspection_category: Mapped[str] = mapped_column(String(32), nullable=False, unique=True)
    measure_record: Mapped[List['MeasureRecordModel']] = relationship(back_populates='inspection_category')


class VehicleInfoModel(BaseModel):
    """"车辆信息表"""
    __tablename__ = 'vehicle_info'
    serial_number: Mapped[str] = mapped_column(String(128), nullable=False, unique=True, info={"description": "流水号"})
    vin: Mapped[str] = mapped_column(String(128), nullable=False, info={"description": "车辆识别代号"})
    plate_type_id: Mapped[int] = mapped_column(Integer, ForeignKey('plate_type.id'), nullable=False,
                                               info={"description": "号牌种类"})
    plate_number: Mapped[str] = mapped_column(String(32), nullable=True, info={"description": "号牌号码"})
    brand: Mapped[str] = mapped_column(String(64), nullable=True, info={"description": "品牌"})
    vehicle_type_id: Mapped[int] = mapped_column(Integer, ForeignKey('vehicle_type.id'), nullable=False,
                                                 info={"description": "车辆类型"})
    vehicle_class_id: Mapped[int] = mapped_column(Integer, ForeignKey('vehicle_class.id'), nullable=True,
                                                  info={"description": "车辆类别"})
    vehicle_model: Mapped[str] = mapped_column(String(128), nullable=True, info={"description": "车辆型号"})
    body_color: Mapped[str] = mapped_column(String(64), nullable=True, info={"description": "车身颜色"})
    number_axes: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "轴数"})
    total_mass: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "总质量"})
    vehicle_owner: Mapped[str] = mapped_column(String(128), nullable=True, info={"description": "机动车所有人"})
    date_first_registration: Mapped[datetime] = mapped_column(Date, nullable=True,
                                                              info={"description": "初次登记日期"})
    manufacturer: Mapped[str] = mapped_column(String(128), nullable=True, info={"description": "制造厂"})
    standard_length: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "标准长"})
    standard_width: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "标准宽"})
    standard_height: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "标准高"})
    standard_wheelbase: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "标准轴距"})
    standard_fence_depth: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "标准栏板深度"})
    standard_curb_weigh: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "标准整备质量"})
    cargo_hold_standard_length: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "标准货箱长"})
    cargo_hold_standard_width: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "标准货箱宽"})
    cargo_hold_standard_height: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "标准货箱高"})
    limit_length: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "限值长"})
    limit_width: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "限值宽"})
    limit_height: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "限值高"})
    tank_standard_length: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "标准罐体长"})
    tank_standard_width: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "标准罐体宽"})
    tank_standard_height: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "标准罐体高"})
    tank_standard_volume: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "标准罐体容积"})
    tank_standard_angle: Mapped[float] = mapped_column(Float, nullable=True, info={"description": "标准罐体角度"})
    # 定义外键关系
    plate_type: Mapped[PlateTypeModel] = relationship(back_populates='vehicle_info')
    vehicle_type: Mapped[VehicleTypeModel] = relationship(back_populates='vehicle_info')
    vehicle_class: Mapped[VehicleClassModel] = relationship(back_populates='vehicle_info')
    measure_record: Mapped[List['MeasureRecordModel']] = relationship(back_populates='vehicle_info')


class MeasureRecordModel(BaseModel):
    """测量记录"""
    __tablename__ = 'measure_record'
    vehicle_info_id: Mapped[int] = mapped_column(Integer, ForeignKey('vehicle_info.id'), nullable=False,
                                                 info={"description": "车辆信息"})
    measure_length: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "检测长"})
    measure_width: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "检测宽"})
    measure_height: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "检测高"})
    measure_wheelbase: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "检测轴距"})
    measure_fence_depth: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "检测栏板深度"})
    measure_curb_weigh: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "检测整备质量"})
    measure_cargo_hold_length: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "检测货箱长"})
    measure_cargo_hold_width: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "检测货箱宽"})
    measure_cargo_hold_height: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "检测货箱高"})
    measure_tank_length: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "检测罐体长"})
    measure_tank_width: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "检测罐体宽"})
    measure_tank_height: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "检测罐体高"})
    measure_tank_volume: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "检测罐容积"})
    measure_tank_angle: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "检测罐体角度"})
    # ---------------差值----------------- #
    length_diff: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "长差值"})
    width_diff: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "宽差值"})
    height_diff: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "高差值"})
    wheelbase_diff: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "轴距差值"})
    fence_depth_diff: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "栏板深度差值"})
    curb_weigh_diff: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "整备质量差值"})
    cargo_hold_length_diff: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "货箱长差值"})
    cargo_hold_width_diff: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "货箱宽差值"})
    cargo_hold_height_diff: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "货箱高差值"})
    tank_length_diff: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "罐体长差值"})
    tank_width_diff: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "罐体宽差值"})
    tank_height_diff: Mapped[int] = mapped_column(Integer, nullable=True, info={"description": "罐体高差值"})
    tank_volume_diff: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "罐容积差值"})
    tank_angle_diff: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "罐体角度差值"})
    # ---------------百分比----------------- #
    length_per: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "长百分比"})
    width_per: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "宽百分比"})
    height_per: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "高百分比"})
    wheelbase_per: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "轴距百分比"})
    fence_depth_per: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "栏板深度百分比"})
    curb_weigh_per: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "整备质量百分比"})
    cargo_hold_length_per: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "货箱长差值"})
    cargo_hold_width_per: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "货箱宽差值"})
    cargo_hold_height_per: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "货箱高差值"})
    tank_length_per: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "罐体长百分比"})
    tank_width_per: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "罐体宽百分比"})
    tank_height_per: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "罐体高百分比"})
    tank_volume_per: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "罐容积百分比"})
    tank_angle_per: Mapped[int] = mapped_column(Float, nullable=True, info={"description": "罐体角度百分比"})
    # ---------------判定----------------- #
    length_judge: Mapped[bool] = mapped_column(Boolean, nullable=True, info={"description": "长判定"})
    width_judge: Mapped[bool] = mapped_column(Boolean, nullable=True, info={"description": "宽判定"})
    height_judge: Mapped[bool] = mapped_column(Boolean, nullable=True, info={"description": "高判定"})
    wheelbase_judge: Mapped[bool] = mapped_column(Boolean, nullable=True, info={"description": "轴距判定"})
    fence_depth_judge: Mapped[bool] = mapped_column(Boolean, nullable=True, info={"description": "栏板深度判定"})
    curb_weigh_judge: Mapped[bool] = mapped_column(Boolean, nullable=True, info={"description": "整备质量判定"})
    cargo_hold_length_judge: Mapped[int] = mapped_column(Boolean, nullable=True, info={"description": "货箱长判定"})
    cargo_hold_width_judge: Mapped[int] = mapped_column(Boolean, nullable=True, info={"description": "货箱宽判定"})
    cargo_hold_height_judge: Mapped[int] = mapped_column(Boolean, nullable=True, info={"description": "货箱高判定"})
    tank_length_judge: Mapped[int] = mapped_column(Boolean, nullable=True, info={"description": "罐体长判定"})
    tank_width_judge: Mapped[int] = mapped_column(Boolean, nullable=True, info={"description": "罐体宽判定"})
    tank_height_judge: Mapped[int] = mapped_column(Boolean, nullable=True, info={"description": "罐体高判定"})
    tank_volume_judge: Mapped[int] = mapped_column(Boolean, nullable=True, info={"description": "罐容积判定"})
    tank_angle_judge: Mapped[int] = mapped_column(Boolean, nullable=True, info={"description": "罐体角度判定"})

    total_judge: Mapped[bool] = mapped_column(Boolean, nullable=True, info={"description": "总判定"})
    measure_time = mapped_column(DateTime, nullable=False, info={"description": "检测时间"})
    inspection_category_id: Mapped[int] = mapped_column(Integer, ForeignKey('inspection_category.id'), nullable=True,
                                                        info={"description": "检验类别"})
    inspection_count: Mapped[int] = mapped_column(Integer, nullable=False,
                                                  default=1, info={"description": "检验次数"})
    picture_path: Mapped[str] = mapped_column(String(256), nullable=True, info={"description": "图片路径json字符串"})
    vehicle_info: Mapped[VehicleInfoModel] = relationship(back_populates='measure_record')
    inspection_category: Mapped[InspectionCategoryModel] = relationship(back_populates='measure_record')


Base.metadata.create_all(bind=engine)
Session = sessionmaker(bind=engine)
